﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace AgileShare.Framework.Library.Helpers
{
    public static class SPPropertyBagHelper
    {
        /// <summary>
        /// Simply adds a key/value pair to the SPWeb AllProperties Hashtable and the
        /// Deprecated SPWeb Property bag without updating
        /// </summary>
        public static void AddProperty(this SPWeb web, string key, string value)
        {
            //bool existsInDeprecatedPropertyBag = !string.IsNullOrEmpty(web.Properties[key]);
            //bool existsInAllPropertiesHashtable = web.AllProperties.ContainsKey(key);
            //bool hasUpperChars = key.ToCharArray().FirstOrDefault(c => char.IsUpper(c)) != null;

            web.Properties[key] = value;
            web.AllProperties[key] = value;
        }

        /// <summary>
        /// Simply removes the property with the given key from the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb property bag without updating
        /// </summary>
        public static void RemoveProperty(this SPWeb web, string key)
        {
            if (web.AllProperties.ContainsKey(key))
            {
                web.AllProperties.Remove(key);
                web.Properties[key] = null;
            }            
        }

        /// <summary>
        /// Adds the given key/value pair to both the SPWeb AllProperties Hashtable and
        /// the deprecated SPWeb Property Bag and Updates both the Property Bag and the SPWeb.
        /// This method ensures the operation is done with System permissions.
        /// </summary>
        public static void AddPropertyAndUpdate(this SPWeb web, string key, string value)
        {
            var properties = new Dictionary<string, string>(1);
            properties.Add(key, value);
            AddPropertiesAndUpdate(web, properties);
        }

        /// <summary>
        /// Adds the given key/value pairs to both the SPWeb AllProperties Hashtable and
        /// the deprecated SPWeb Property Bag and Updates both the Property Bag and the SPWeb.
        /// This method ensures the operation is done with System permissions.
        /// </summary>
        public static void AddPropertiesAndUpdate(this SPWeb web, IDictionary<string, string> properties)
        {
            SPImpersonationHelper.DoUnsafeUpdateAsSystemUser(web, delegate(SPWeb systemWeb)
            {
                foreach (var pair in properties)
                {
                    AddProperty(systemWeb, pair.Key, pair.Value);
                }

                systemWeb.Update();
                systemWeb.Properties.Update();
            });
        }

        /// <summary>
        /// Removes the property with the given key from both the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb Property Bag and updates both the Property Bag
        /// and the SPWeb.  This method ensures the operation is done with System permissions.
        /// </summary>
        public static void RemovePropertyAndUpdate(this SPWeb web, string key)
        {
            RemovePropertiesAndUpdate(web, key);
        }

        /// <summary>
        /// Removes the properties with the given keys from both the SPWeb AllProperties
        /// hashtable and the deprecated SPWeb Property Bag and updates both the Property Bag
        /// and the SPWeb.  This method ensures the operation is done with System permissions.
        /// </summary>
        public static void RemovePropertiesAndUpdate(this SPWeb web, params string[] keys)
        {
            SPImpersonationHelper.DoUnsafeUpdateAsSystemUser(web, delegate(SPWeb systemWeb)
            {
                foreach (var key in keys)
                {
                    RemoveProperty(systemWeb, key);
                }

                systemWeb.Update();
                systemWeb.Properties.Update();
            });
        }

        /// <summary>
        /// Safely gets a property value from the SPWeb Property Bag
        /// </summary>
        public static string GetPropertyValue(this SPWeb web, string key)
        {
            if (web.AllProperties.ContainsKey(key))
                return web.AllProperties[key].ToString();

            return string.Empty;
        }

        /// <summary>
        /// Reads a property value from the Farms property bag with elevated priveleges
        /// </summary>
        public static string GetFarmProperty(string key)
        {
            return GetFarmProperty<string>(key);
        }

        /// <summary>
        /// Reads a property value from the Farms property bag with elevated priveleges
        /// </summary>
        /// <typeparam name="T">T can be a string, DateTime, or an int</typeparam>
        public static T GetFarmProperty<T>(string key)
        {
            T value = default(T);
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                var farmProperties = SPFarm.Local.Properties;
                if (farmProperties.ContainsKey(key))
                    value = (T)farmProperties[key];
            });
            return value;
        }

        public static string GetWebApplicationProperty(this SPWeb web, string key) {
            return GetWebApplicationProperty<string>(web.Url,key);
        }

        /// <summary>
        /// 获取Web Application 属性
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="requestUrl"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public static T GetWebApplicationProperty<T>(string requestUrl, string key) {
            T value = default(T);
            SPSecurity.RunWithElevatedPrivileges(delegate() {
                SPWebApplication webApp = SPWebApplication.Lookup(new Uri(requestUrl));
                var webAppProperties = webApp.Properties;
                if (webAppProperties.ContainsKey(key))
                {
                    value = (T)webAppProperties[key];
                }
            });
            return value;
        }

        /// <summary>
        /// 添加属性到WebApplication
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="properties"></param>
        public static void AddWebApplicationProperty(string requestUrl, Dictionary<string, string> properties)
        {
            
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPWebApplication webApp = SPWebApplication.Lookup(new Uri(requestUrl));
                var webAppProperties = webApp.Properties;
                foreach (var item in properties)
                {
                    if (webAppProperties.ContainsKey(item.Key))
                    {
                        webAppProperties[item.Key] = item.Value;
                    }
                    else
                    {
                        webAppProperties.Add(item.Key, item.Value);
                    }                    
                }
                webApp.Update(true);                 
            });
        }

        public static void AddFarmProperty(Dictionary<string, string> properties)
        {
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                SPFarm farm = SPFarm.Local;
                var webAppProperties = farm.Properties;
                foreach (var item in properties)
                {
                    if (webAppProperties.ContainsKey(item.Key))
                    {
                        webAppProperties[item.Key] = item.Value;
                    }
                    else
                    {
                        webAppProperties.Add(item.Key, item.Value);
                    }
                }
                farm.Update(true);
            });
        }
    }
}
